//
// Created by haoly on 2025/5/23.
//
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include "ST.h"

void test_init();
void test_insert_search();
void test_delete();
void test_select();
void test_sort();
void print_item(Item item);
void test_count();
void test_boundaries();
int main(int argc, char *argv[]) {
    test_init();
    test_insert_search();
    test_delete();
    test_select();
    test_sort();
    test_count();
    test_boundaries();
    return 0;
}

// 初始化符号表
void test_init() {
    STinit(maxKey);
    for (int i = 0; i < maxKey; i++) {
        assert(STsearch(i) == NULLitem); // 初始化后所有位置应为空
    }
    printf("test_init passed.\n");
}

// 测试插入和搜索
void test_insert_search() {
    STinit(maxKey);

    Item item1 = malloc(sizeof(*item1));
    item1->key = 5;
    item1->value = 100;
    STinsert(item1);
    assert(STsearch(5) != NULLitem);
    assert(value(STsearch(5))== 100);

    Item item2 = malloc(sizeof(*item2));
    item2->key = 3;
    item2->value = 200;
    STinsert(item2);
    assert(STsearch(3) != NULLitem);
    assert(value(STsearch(3))== 200);

    Item item3 = malloc(sizeof(*item3));
    item3->key = 5;
    item3->value = 300;
    STinsert(item3);
    assert(STsearch(5) != NULLitem);
    assert(value(STsearch(5))== 300);

    free(item1);
    free(item2);
    free(item3);
    printf("test_insert_search passed.\n");
}

// 测试删除功能
void test_delete() {
    STinit(maxKey);
    Item item = malloc(sizeof(*item));
    item->key = 2;
    item->value = 50;
    STinsert(item);
    STdelete(item);
    assert(STsearch(2) == NULLitem);

    // 删除不存在的键
    Item dummy = malloc(sizeof(*dummy));
    item->key = 7;
    item->value = 0;
    STdelete(dummy); // 应无错误
    assert(STsearch(7) == NULLitem);

    printf("test_delete passed.\n");
}

// 测试选择操作
void test_select() {
    STinit(maxKey);
    Item item = malloc(sizeof(*item));
    Item item2 = malloc(sizeof(*item2));
    Item item3 = malloc(sizeof(*item3));
    item->key = 3;
    item->value = 1;
    item2->key = 1;
    item2->value = 2;
    item3->key = 4;
    item3->value = 3;
    STinsert(item);
    STinsert(item2);
    STinsert(item3);

    // 验证选择顺序应为1,3,4
    assert(key(STselect(0)) == 1);
    assert(key(STselect(1)) == 3);
    assert(key(STselect(2)) == 4);
    assert(STselect(3) == NULLitem); // 越界返回NULL

    printf("test_select passed.\n");
}

// 测试排序遍历
void test_sort() {
    STinit(maxKey);
    Item item = malloc(sizeof(*item));
    Item item2 = malloc(sizeof(*item2));
    Item item3 = malloc(sizeof(*item3));
    item->key = 5;
    item->value = 10;
    item2->key = 2;
    item2->value = 20;
    item3->key = 8;
    item3->value = 30;

    STinsert(item);
    STinsert(item2);
    STinsert(item3);

    // 预期访问顺序：2,5,8
    printf("Expected order: 2(20) -> 5(10) -> 8(30)\nActual order: ");
    STsort(print_item);
    printf("\n");
}

// 辅助打印函数
void print_item(Item item) {
    printf("%d(%d) ", item->key, item->value);
}

// 测试计数功能
void test_count() {
    STinit(maxKey);

    assert(STcount() == 0);
    Item item = malloc(sizeof(*item));
    Item item2 = malloc(sizeof(*item2));
    Item item3 = malloc(sizeof(*item3));
    item->key = 0;
    item->value = 1;
    item2->key = 1;
    item2->value = 2;
    item3->key = 2;
    item3->value = 3;

    STinsert(item);
    STinsert(item2);
    STinsert(item3);

    STdelete(item2);
    assert(STcount() == 2);

    printf("test_count passed.\n");
}

// 边界测试：最小和最大键
void test_boundaries() {
    STinit(maxKey);

    Item min_item = malloc(sizeof(*min_item));
    Item max_item = malloc(sizeof(*max_item));
    min_item->key = 0;
    min_item->value = 100;

    max_item->key = maxKey-1;
    max_item->value = 200;

    STinsert(min_item);
    STinsert(max_item);

    assert(STsearch(0) != NULLitem);
    assert(STsearch(maxKey-1) != NULLitem);

    printf("test_boundaries passed.\n");
}